e. Just leave all options as is, and hit return. Nosy will go through what it terms a TreeWalk which means that it will recursively analyze the program and generate it's decompiled code. Working with Nosy. Since I don't want to re-type the entire Nosy manual, I am going to list just the basics. There are some great features that I never use and don't even know how to initiate without referring to the manual and these will be omitted. Everything I use to crack software will be covered in detail. At this point, Nosy will present you with several windows: a Code Blks window, listing all procedures in the decompiled file; a Notes window which Nosy will use to display information; and a Mystery window, listing things that Nosy had trouble with during decompilation. Nosy can also display a list of all Data Blocks which are chunks of code that either did not make sense as executable code, or were referenced as data (Nosy looks for PEA and LEA to determine this and looks for JMP, JSR, and BSR to find individual procedures). Notes cannot be closed, so ignore it, and Mystery has things that - to date at least - don't matter that much to the cracker. When working with Nosy, you can at any time select the name of a code or data block and hit CMD-d to display it in a new window. Before examining the menu commands, lets look at a basic Nosy listing and see what Nosy tells us. This is the procedure called Eject from the file Font/DA Mover. This is the file I will describe in detail later. BD4: QUAL Eject ; b# =79 s#1 =proc47 vbt_1 VEQU -64 param2 VEQU 8 param1 VEQU 10 funRslt VEQU 14 BD4: VEND ;-refs - 2/CLOSEMYF BD4: 4E56 FFC0 'NV..' Eject LINK A6,#-$40 BD8: 41EE FFC0 200FFC0 LEA vbt_1(A6),A0 BDC: 316E 0008 0016 2000008 MOVE param2(A6),ioVRefNum(A0) BE2: 216E 000A 0012 200000A MOVE.L param1(A6),ioNamePtr(A0) BE8: A017 '..' _Eject ; (A0|IOPB:ParamBlockRec):D0\OSErr BEA: 3D40 000E 200000E MOVE D0,funRslt(A6) BEE: 4E5E 'N^' UNLK A6 BF0: 225F '"_' POP.L A1 BF2: 5C8F '\.' ADDQ.L #6,A7 BF4: 4ED1 'N.' JMP (A1) OK, The first column contains the code resource-relative address of the instructions. To the right of this is the hex listing of the instruction, followed by an ascii display, followed by the actual assembly instruction. The first line tells you the following: The name of the procedure (either a meaningful name Nosy found somewhere, or a generic procN where N tells where the procedure falls sequentially in the file), the block number (similar to proc number except this takes into account data blocks as well as procedure blocks), the segment or CODE resource ID #, and the actual procedure number. So in the above example, we are looking at Eject, it is the 79th block in the file (counting data blocks), it is in code resource ID 01, and it is the 47th procedure block in the file. So we could open CODE 01 in Resedit, skip down to BD8 and see the hex codes that Nosy lists. Whe BD8 and not BD4 like it says above? Well, on disk, a CODE resource has 4 header bytes (whose meaning escapes me at the moment) so we have to add 4 to the Nosy address to find the correct Resedit address. Below this information will be listed any local variables used (they will always contain an underscore) along with their relative offsets from the procedure, then any parameters passed along with their offsets. If there is a result that will be passed back to the calling procedure, it will be listed as funRslt (as it is here). Don't worry about all the offset information as Nosy will refer to parms and local variables by their symbolic names. VEND denotes the end of the variable list. Next comes any references to this procedure - any procedures that call this procedure. Finally comes the actual listing. Occasionally, Nosy will stick more than one procedure in a window. If this happens, each procedure will have the above header. Nosy also might include data blocks in a procedure's window and it will have the word dataXX to the left of it. Menu Commands  This is pretty straight forward and should require no explanation. Save As... will allow you to save as text a procedure or data window. This way you can type in your own comments and save them. I never use this feature, however. TTY mode allows some of Nosy's extra features. In previous version, TTY was the only mode and I imagine was hell to use. With the newer version, 2.0 or higher I believe, you can stay in the window mode that you are currently in and never use TTY mode.  OK, the first two sections are standard. Find will find the next occurence of whatever you have selected. For example, you can select a local variable name and hit cmd-f to find the next time it occurs in the current window. If nothing is selected, Nosy presents a dialog allowing you to enter a search string. Change brings up a standard search/replace dialog - similar to Word. Goto Line allows the user to goto a specified line number in the front window. Grab Clip & Find operates like Find except that the clipboard is used as the search string. Show Insert pt scrolls the window to display the cursor (if you had scrolled the cursor off the screen). insert pt to Top places the cursor at the top of the screen (line 1). sel to Notes copies the current selection into the Notes window.  Code|Data blk displays the currently selected code or data block in a new window. For example if you select a procedure from the code blocks window and hit cmd-d, the procedure will be displayed in a new window. If there is no current selection then Nosy will request a proc name via a dialog. Refs to Active only if a procedure name is selected. Displays all procedures that call the selected procedure. Using this, you can see any part of the program that is calling a particular procedure. Call chain Similar to Refs to. Any procedure that calls the selected procedure is also treated with Refs to. For example, you select a procedure called proc5. Doing a Refs to shows all procs that call proc5 - let us say for example, pro10 and proc 15. If you had selected proc5 and done a Call chain instead of Refs to, then first proc10 would be displayed along with any proc that called and so on backwards until the chain ends. Then proc15 would be listed along with any procs that call it, and so on until the chain ends. This is an excellent way of tracing a procedure that draws an error dialog back to the procedure that actually generated the error. Sys syms map Displays all system global variables along with any procedures that reference them. An example might be the system global MemErr which contains any OS errors. Nosy would display any procedures that reference MemErr - note that this command displays ALL system globals and their referencing procedures. Trap refs map This is a beauty. This will list all traps called by the program and the procedures that call them. If a program is asking for a key disk, use this command to search for procedures that call either ModalDialog or one of the Alert traps. Globals map Displays all program global variables and the procedures that use them. Rsrc map Lists all program resources, their lengths, and names if any. Strings Lists all strings and the procedures that reference them. I am not sure what Nosy defines as a string, but try it on Font/DA Mover to see. Data Blks Displays a window listing all data blocks. Case jumps Displays any procs containing a structure that resembles a case statement. Mystery procs Opens the Mystery Procs window showing any procedures that Nosy was unsure how to handle. ROM Patch Info Unknown. My outdated docs don't even mention this command. Bad Blks Displays information about any blocks that Nosy thought were code but contained illegal instructions so Nosy converted them to data blocks. Encrypted code would fit into this category. Blk tbl Displays the following for all blocks: name, segment number (resource ID #), start address, and length. Code Blks Displays the Code Blks window listing all code blocks.  Review... Lets you review data blocks, optionally converting them to code blocks. More on this later. Link Jmp to Tbl Defines the link between a mystery jump and and a data block. To use it, select the address of a mystery JMP and choose the command. More on Jump Tables later. Code to Data Converts a selected code block to a data block. The blocks name won't change until the next Explore (see below). Is Proc Converts a selected data block to a code block. The block's name won't change until the next Explore. JSR is JMP Tells Nosy that a JSR is really a JMP. Sometimes a JSR is followed by data - which will look like jiberish code. The called procedure then pops the return address off the stack and uses that address as a pointer to a data block with no intention of returning to the calling procedure. To use this command, select the destination of the JSR (e.g. for JSR proc100, select proc100) and choose this command. Explore Initiates a TreeWalk. This allows Nosy to re-examine the program using any changes you might have made (i.e. converting data blocks to code blocks, etc).  Extract Comments Extracts comments from the selection (usually an entire procedure window) into a window entitled Comments. See section on commenting below. Append to .aci Appends selected comments (created using the above) to an aci (additional comment information) file. Later, this file can be re-merged into the dissassembly. name cHange Changes the selected name to whatever you type in. Use this to rename procedures from the generic procN to a name that tells you what the procedure basically does. The change will be immediate and global. Addr to File pos Converts a selected address (the leftmost information for a procedure display) into file-relative information, displaying a file-relative offset (in hex), block or sector number, and the block offset to the start of the address. This might be handy if you were using a file editor (instead of Resedit which allows you to simply open the proper code resource) to edit the file. Convert to .asm fmt Converts the current procedure window to asm format by removing the addresses and hex and ascii data. Cannot be undone - you must close the window, not save changes, and re-open it. save .snt, reRead .aci Saves a .snt file for the dissassembled program and re-reads the comment file if it exists. .snt files (saved Nosy tables) are a means of saving your dissassembly mid-session. All changes are remembered so when you re-open the file later, you begin right where you left off instead of doing a TreeWalk all over again, etc. Journal commands A checkmark next to this indicates that all your commands are being saved to a text file. The file will not actually be saved unless you specify so when you Quit - see quitting later. Proc rel addresses When checked displays the address of each instruction as procedure relative (starting at zero for each procedure instead of starting at zero for each code resource). format Maps by Addr When checked, Nosy will change the way it displays its various maps, i.e. Sys syms, Trap refs, etc. under the Display menu. Instead of proc names, Nosy will display the segment number, and the segment offset. But - if Proc rel addresses is also checked, then Nosy will replace the proc names with a proc name followed by a + followed by the procedure relative offset. Try it out if this doesn't make sense. cmds to Notes Wind Not yet implementated - like a lot of great features (see below). Set Source Path Not in my manual - you're on your own. Extract Map Names Not in my manual - on you're own again. This doesn't seem to do anything, though, when I try it. Unfortunately, the Search_Rsrc menu is totally disabled. Maybe the next version...  Record/ALL names Lists all Macintosh data structures that Nosy currently knows. Fields of Depends on the selection: 1) a datatype (e.g. Dialog Record - or anything listed by the previous command) - describes all fields for the datatype. 2) datatype@address - displays the current values for the datatype if one exists at the specified address. 3) @address - displays hex/ascii dump at specified address. OS Traps Lists all known Operating System Traps and their parameters. TB Traps Lists all known ToolBox traps and their parameters. Sys Syms Lists all known System Symbols. Sys Errs Lists all known System Errors and their codes. Constants Lists all known Macintosh Constants. Note that my copy of Nosy contains an error in this window - it specifies that constants in brackets can be selected and viewed by pressing cmd-?. Use cmd- (or select Fields of from the Tables menu). Ascii Decimal/Hex/Ascii lookup table. Calculate Evaluates selected expressions which can contain mathematical operators, system globals, program globals, IM datatypes, registers etc. Use # to force decimal (#10) and $ for hex ($10). Convert Hex to Dec Converts a selected number to decimal, ascii, and system symbol equivalent if there is one. add/ZAP Type /Defs No idea. Note on commands requiring a selection (Calculate, etc.) You may have noticed that often there is no place to enter the text you want to select. In cases like these, type your text into the Notes window, select it, and choose the command you wish. Reviewing Data Blocks This is the process by which you tell Nosy that it has mistakenly made a piece of code a data block. Once you initiate the Review... command, Nosy will show you each data block in sequence and give you a chance to work on it. Note that you may never need to do this to crack a program - god knows I never use it unless I am really having problems. This section is to provide you with some idea of what Nosy can do. Here is a typical display after selecting Review... from the Reformat menu. The Data Blk window displays the data block, the window directly underneath this will display the section of code that references that data block (if their is one) and the Cmd window awaits your input. There are about a zillion things you can do, but the most important one is the c command.  If your press c and return, Nosy shows you what the data block looks like in assembly:  Notice that this looks like pretty good code! Also note that Nosy has placed i in the Cmd window anticipating that you will want to change this to code. Here are all the commands available: H takes 2 parameters: 1) either L,W, or B for Longword, Word, or Byte and 2) the number of entries per line. Formats the block as Hex bytes. Example: HL2 would format the block as hex longwords, 2 per line. D same as H (above) but formats block as decimal entries. A same as H (above) but formats the block as ascii entries. Z same as H (above) but formats the block as zero entries. W Formats the block as a word-aligned Pascal string. S Formats the block as a Pascal string. WZSTR Formats the block as a word-aligned zero-terminated string. Z Formats the block as a zero-terminated string. J Formats the block as a set of Jump Table entries - each word is taken as an offset from the beginning of the data block to a common procedure and these jumped to spots are marked as common blocks (a common block - denoted com_nn - is any procedure executed via JMP instead of JSR or BSR). If you do this, you need to use the Link Jmp to Tbl command to link the jump table to its jump command. See Jump Tables below. JUMPP Same as J except that the entry points are marked as procedures instead of common blocks. BRAL Formats the block as code. Any instructions that are BRAnched to are marked with local markers (as in a standard Nosy listing). BRAC Same as above except that instructions reached via BRA are marked as common blocks. U Undoes any formatting changes. C Changes the block to a code listing and brings up the code menu - discussed below. Q Exits Review mode. N takes an integer parameter X. Splits the block into two blocks, the first block getting X words (remember a word is two bytes). NB same as above except the parameter specifies bytes instead of words. NL same as above except the parameter is a segment-relative address specifying the end of the the first block. NU takes an optional search string as parameter. Splits the block with the first block ending upon finding the search string. If no string is supplied, Nosy searches for a logical procedure end (RTS, JMP(AX) ). The block is formatted as code and the code menu is displayed. NW Splits the block in two, the first block being made a word-aligned Pascal string. N* Splits the block in two. Uses the first longword to determine the length of the first block. O If the previous block is a data block, then combine it with the current one. ADDR Formats the block as a list of word-length procedure block addresses. LADRC Formats the block as a list of longword-length common block addresses. LADRP Formats the block as a list of longword-length procedure block addresses. Saves changes, and takes you to the next block. The Code Menu Commands: these come up if you use c or nu to change the block to a code listing. U Undo any changes to size or format and takes you back to the Review menu. I Tells Nosy to keep the block as code and return to the Review menu. Q Exits Review mode. R Changes block back to data, but retains any size changes you may have made. N Same as the N commands above. Same as above - returns to the Review menu. Once you have finished Reviewing data blocks, you must select Explore from the Reformat menu to have Nosy incorporate any changes into its lists. Working with Jump Tables A jump table is a means of efficiently transferring control to a procedure. An example of a jump table would be a program that receives an event (as most mac programs do) and then has to execute a procedure depending on what the event was. Font/DA Mover has an extermely simple jump table - actually it is not a true jump table - in which the button the user clicks is returned to its main event loop as an integer. The program then repeatedly subtracts one from the integer and branches to an appropriate procedure when the integer has been reduced to zero. A more common (and true) jump table consists of a list of offsets. The program then takes an integer which tells it which entry in the table to use, multiplies it by 2 (assuming each entry is two bytes in length) and then indirectly jumps to the correct procedure. Here is an example taken from the Nosy manual (this is from the System File's .MPP driver): LEA data4,A3 ADDA D3,A3 ADDA D3,A3 MOVEA (A3),A3 PEA .MPP ADDA.L (A7)+,A3 JMP (A3) data4 DC.W $82,$280,$26C,$3C, etc As gross as this looks, lets see what it is doing. At the start, D3 contains the selector that determines which entry in the table to use. A3 is loaded with the address of the jump table. D3 is added to it twice (we could have doubled D3, then added it) so that now A3 contains the address of the proper jump table entry. The instruction MOVEA (A3),A3 grabs the jump table entry (which is simply an offset from the start of the program to the correct procedure) and puts that entry back into A3. Next the address of the program start (.MPP) is pushed on the stack, and this value is added to A3 to produce the actual address of the procedure (the address is the start of the program plus the offset). Now A3 is setup, so the program Jumps to the address in A3. If you don't mind looking at this type of listing (and I don't since it probably is not the copy protection - although it might be jumping to the copy protection) then you need go no farther. But Nosy can set this up to look much nicer. To fix this up, select the address (the far left column) of the Jump instruction - in this case, the JMP (A3). Now choose Link Jmp to Tbl from the Reformat menu and a dialog box appears requesting the name of the jump table's block - in our case that would be data4. Click continue and a new dialog appears. The first thing we need is the table format. There are three choices: JUMPP - tells nosy to label the jumped to procedures as procedure blocks; JUMPC - tells Nosy to label the jumped to procedures as common blocs; JUMPL - tells Nosy to label the jumped to procedures with local labels in the same block as the jump table. To figure out which one to use (and it is really a matter of preference), decide if you want to break the whole thing up into many procedures, or keep it as one large procedure with tons of local labels. If the procedure is a massive one, you may want to break it up (and I would recommend JUMPP - but then, I like proc labels better than com labels), otherwise, use JUMPL. Next we need the number of jumps. Just count the number of entries - but be careful: you need to decide the size of each entry in the table. Note the DC.W next to data4. This means that Nosy is showing you individual words so you can just count the number of entries. But if Nosy is using DC.B, then it is showing you bytes, so you would have half as many word length entries. Finally, we need the Table Bias. Bias is a parameter that Nosy uses to determine the actual procedure address of a non-standard jump table. To calculate this, use this formula: Bias = Address of JumpTable + Offset - TargetAddress. The tricky thing is to deterine the TargetAddress. In the above example, it is easy, since the code clearly refers to the start of itself (it refers to the address of .MPP). JumpTable is the address (leftmost column in the listing) of the start of the jump table, and Offset is the first word-length offset in the table. Note that your calculations will result in a hex bias - Nosy needs you to change it to decimal. Click Accept, do another Explore, and that is it! Now the listing looks like: JMP (A3) JBIAS 92 data4 JUMP procA JUMP procB JUMP procC etc. Notice that Nosy uses JUMP to distinguish it from the instruction JMP. Once this is set up, it is a cinch to see where the jump table is jumping - provided you can deduce the selector. Most of the time Nosy works wonders with jump tables, and the few times it has problems (it will list these problems in the Mystery window) I have found it not worth the work to convert them to the above format. Commenting Your Listings There are a couple of cool features that I am not going to explain regarding commenting simply because I have never used them and the manual I have isn't the most verbose. Basically, you can put comments on any line that Nosy hasn't already commented. All comments must start with a semi-colon. Once you have all the comments you want, do a cmd-a to select all, and choose Extract Comments from the Misc menu. Nosy will extract all your comments into a comments window. Now hit cmd-a again, and choose Append to .aci from the Misc menu. This will save your comments. Now close the procedure window and don't save changes. Select Save .snt, reRead .aci from the Misc menu. Nosy may ask you if you want to delete something or other which it claims saves space in the Debugger. Since we are not using the Debugger, choose No. Now when you open the procedure again, you comments appear. There is one feature I will attempt to explain, because it could be a serious boon. There a several slash (/) commands Nosy understands. One in particular, /w, works like this: Anytime a register is setup to contain a pointer to a Mac structure, you can have Nosy automatically show the structure whenever the register is referenced. Here is an example: PEA data24 ; len = 206 _OpenPort ; (port:GrafPtr) LEA data24,A2 ; len = 206 MOVE #4,68(A2) MOVE #9,74(A2) Note in the 3rd line that A2 is given the GrafPtr. Since GrafPtr is a pointer to a valid Mac structure (GrafPort), we could use the /w command as follows: click at the end of the 3rd line and hit return (so we are not commenting on a line that Nosy has already commented). Enter /wGrafPort. Now save the comments as illustrated above. When the proc is re-opened it shows the following: PEA data24 ; len = 206 _OpenPort ; (port:GrafPtr) LEA data24,A2 /w GrafPort MOVE #4,txFont(A2) MOVE #9,txSize(A2) Using this technique, Nosy will use the fields of the structure instead of the actual offsets from the register. This will work for any valid Mac structure. I haven't used this feature (I just noticed it when compiling this manual) so that is all I will say - feel free to experiment. Well, I guess the next thing to do is start looking at some serius code listings pulled directly from Nosy (and not stuff I made up on the fly). Nosy has shorthand notations for certain operations, most commonly for stack operations. The two to watch out for are PUSH and POP (btw, TMON does not use this notation, but rather uses the standard notation found in any assembly book). PUSH is the equivalent of putting the operand onto the stack using auto pre-decrement. POP is the same as grabbing the operand off the stack using auto post-increment. Let's take a look at some code listings from Font/DA Mover 3.8. I selected this program so that you can pull up the same listings that I will refer to in Nosy. First take a look at the initial procedure: DA Mover. There will always be a procedure whose name is the same as the program you are de-compiling. This procedure (DA Mover in this case) is the first procedure the program executes when launched. 430: QUAL DA Mover ; b# =12 s#1 =proc4 OK, I will stick my notes right in the listing (below or to the right of what I am refering to), so bear with me. Note the first line (above). We are looking at block 12, segment (or CODE resource #) 1, and it is the 4th procedure in the program. The first few lines will do some startup stuff that I do not fully understand and so I will skip it. 430: 4EBA 0C48 100107A DA Mover JSR proc70 Proc 70 is just an RTS 434: 4E56 0000 'NV..' LINK A6,#0 438: 2C5F ',_' POP.L A6 43A: 4EBA 0C40 100107C JSR proc71 Proc 71 calls _RTINIT which seems to be a common step for MPW compiled programs. It then initializes some global variables. Let's skip all this. 43E: 486D 024A 3000000 PEA proc232(A5) 442: A9F1 '..' _UnLoadSeg ; (Proc:ProcPtr) Here we are dumping an un-needed procedure. Now, looking at the listing from here, notice the procedures that get called - two without labels, then SetUp, MakeAWin and FinderSE and finally MainEven which sounds suspicially like an event loop. Let's check out these procedures. 444: 4EBA 05E2 1000A28 JSR proc28 If you look at this procedure, you see several references to memory stuff like ApplHeap, ApplZone, Rom85, etc. Looks like this is checking for enough memory or something. Not too interesting. 448: 4EBA 021E 1000668 JSR proc10 This proc looks to be changing a few traps. Note that it allocates a new pointer (NewPtr trap) and then calls GetTrapAddress, and then SetTrapAddress. 44C: 4EAD 01F2 2005092 JSR SETUP(A5) Take a look at this listing below the current one: 450: 4EAD 01FA 2005852 JSR MAKEAWIN(A5) Draw the main dialog. 454: 4EBA FCC2 1000118 JSR FINDERSE Checks if user launched a suitcase and if so, opens it. 458: 4AAD F4F0 -$B10 TST.L glob26(A5) Verify the main memory handle. 45C: 6706 1000464 BEQ.S lae_1 Branch if it is empty. 45E: 4EBA FBA0 1000000 JSR MAINEVEN Do the actual program until user Quits. 462: 6008 100046C BRA.S lae_2 Exit without error. 464: 3F3C 0031 '?<.1' lae_1 PUSH #49 Out of Memory Error. 468: 4EAD 01CA 200023C JSR DOALERT(A5) Do an Out of Memory alert 46C: 4EBA FF86 10003F4 lae_2 JSR DOCLEANU From here, the program exits. 470: 4EAD 01D2 20002B2 JSR MYEXITTO(A5) 474: 4EBA 0C2A 10010A0 JSR %INITHEA 478: 4EBA 0C2C 10010A6 JSR proc73 47C: 4E75 'Nu' RTS 47E: 4E5E 4E75 C64F 4E54 data9 DNAME FONT_DA_,4 48A: '..' data10 DC.W 0 Here is the SetUp Procedure: 5092: QUAL SETUP ; b# =467 s#2 =proc199 vho_1 VEQU -12 Only one local variable, no parameters. 5092: VEND ;-refs - 1/DA Mover Only called via DA Mover. 5092: 4E56 FEE6 'NV..' SETUP LINK A6,#-$11A Setup a Stack frame for local variables 5096: 48E7 0118 'H...' MOVEM.L D7/A3-A4,-(A7) Save D7,A3 and A4 on stack 509A: 7E01 '~.' MOVEQ #1,D7 Loop coming up, this inits the loop counter. 509C: 6006 20050A4 BRA.S lho_2 And branch into the loop. 509E: 4EAD 00D2 1000AB0 lho_1 JSR MoreMasters(A5) 50A2: 5247 'RG' ADDQ #1,D7 Increment loop counter. 50A4: 700F 'p.' lho_2 MOVEQ #15,D0 50A6: B047 '.G' CMP.W D7,D0 Test if loop done... 50A8: 6CF4 200509E BGE lho_1 If not, branch back. OK, take a look at the above code. First, D7 is initialized to 1 and then the program branches down to lho_2. The loop test is setup here (15 is the end of the loop). At the compare, ask yourself, is D0 greater than or equal to D7? Well, the first time, D0 is 15 and D7 is 1 so the loop branch will execute. So, MoreMasters is called, 1 is added to the loop counter, and then the loop is checked again. This will loop 15 times (until D7 has 16 in it). MoreMasters is a trap (in this case, the procedure called MoreMasters will execute the trap) that causes a block of master pointers to be allocated in the current heap zone. See Inside Mac's (here on referred to as IM) Memory Manager section for a better description. 50AA: 486D F420 -$BE0 PEA glob3(A5) Push the address of glob3 on the stack. 50AE: A86E '.n' _InitGraf ; (globalPtr:Ptr) InitGraf, we see in IM, that InitGraf must be called once near the start of a program. It requires one parameter, a pointer to the first QD global variable. This parameter is first pushed on the stack in the previous instruction. 50B0: A8FE '..' _InitFonts These traps can all be found in IM. 50B2: A912 '..' _InitWindows 50B4: 2F3C 0000 FFFF '/<....' PUSH.L #$FFFF 50BA: 201F ' .' POP.L D0 50BC: A032 '.2' _FlushEvents ; (whichMask,stopMask:EventMask) 50BE: A9CC '..' _TeInit 50C0: 42A7 'B.' CLR.L -(A7) Note that InitDialogs needs a ProcPtr (a long word). The clr command here uses auto pre-decrement to push a NIL pointer onto the stack. 50C2: A97B '.{' _InitDialogs ; (resumeProc:ProcPtr) 50C4: A930 '.0' _InitMenus 50C6: 486E FFF4 200FFF4 PEA vho_1(A6) OK, notice the VAR in the trap below. This means that info will be returned via the parameter we push on the stack. So, after the trap, vho_1 will be a GrafPtr (whereas before the trap, god knows what is in it). 50CA: A910 '..' _GetWMgrPort ; (VAR wPort:GrafPtr) 50CC: 2F2E FFF4 200FFF4 PUSH.L vho_1(A6) Now, our GrafPtr is used to set the current Port. 50D0: A873 '.s' _SetPort ; (port:GrafPtr) 50D2: 206E FFF4 200FFF4 MOVEA.L vho_1(A6),A0 Now A0 contains our GrafPtr. 50D6: 4868 0008 'Hh..' PEA 8(A0) This instruction says to add 8 to A0,and push that address on the stack. 50DA: A87B '.{' _ClipRect ; (r:Rect) 50DC: 2F3C 000E 000C '/<....' PUSH.L #$E000C The MoveTo trap requires two integers to be passes, but only one value is being pushed on the stack. Since the instruction says to push l